package com.guigu.yh.springcloud.controller;

import com.guigu.yh.springcloud.common.JsonResult;
import com.guigu.yh.springcloud.entities.Payment;

import com.guigu.yh.springcloud.loadbalance.MyLoadBalance;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;
import java.net.URI;
import java.util.List;

/**
 * 订单控制器
 *
 * @author zyh
 * @version 1.0.0
 * @date 2022/08/16
 */
@RestController
@Slf4j
public class OrderController {
    /**
     * 支付服务地址，不使用注册中心时，远程服务地址需要固定写死。
     */
    //public static final String PAYMENT_URL = "http://localhost:8001";
    /**
     * 支付服务地址，使用注册中心时，无需关心服务提供者的具体地址与端口号，只需要关注服务名即可
     */
    public static final String PAYMENT_URL = "http://CLOUD-PAYMENT-SERVICE";

    @Resource
    private RestTemplate restTemplate;

    @Value("${eureka.instance.instance-id}")
    private String eurekaInstanceId;

    @Resource
    private DiscoveryClient discoveryClient;


    @Resource
    private MyLoadBalance myLoadBalance;

    /**
     * 创建
     *
     * @param payment 付款
     * @return {@link JsonResult }<{@link Payment }>
     * @author zyh
     * @date 2022/08/16
     * @version 1.0.0
     */
    @PostMapping("payment/create")
    public JsonResult<Payment> create(Payment payment) {
        log.info(eurekaInstanceId + "利用RestTemplate调用远程http服务create");
        //注意：被调用的远程服务接口参数需要加上@RequestBody注解，否则属性无法传递到下游的远程服务
        return restTemplate.postForObject(PAYMENT_URL + "/payment/create", payment, JsonResult.class);
    }

    /**
     * 获取payment对象
     *
     * @param id id
     * @return {@link JsonResult }<{@link Payment }>
     * @author 张颖辉（zyh）
     * @date 2022/08/20
     * @version 1.0.0
     */
    @GetMapping("payment/get/{id}")
    public JsonResult<Payment> getPayment(@PathVariable("id") Long id) {
        log.info(eurekaInstanceId + "利用RestTemplate调用远程http服务getPayment");
        return restTemplate.getForObject(PAYMENT_URL + "/payment/get/" + id, JsonResult.class);
    }

    /**
     * 获取payment对象
     * 使用 getForEntity() 实现
     *
     * @param id id
     * @return {@link JsonResult }<{@link Payment }>
     * @author 张颖辉（zyh）
     * @date 2022/08/20
     * @version 1.0.0
     */
    @GetMapping("payment/getForEntity/{id}")
    public JsonResult<Payment> getForEntity(@PathVariable("id") Long id) {
        log.info(eurekaInstanceId + "利用RestTemplate调用远程http服务getPayment");
        /*ResponseEntity 包含了更多的重要信息，例如，响应头，响应状态码，响应体等*/
        ResponseEntity<JsonResult> responseEntity = restTemplate.getForEntity(PAYMENT_URL + "/payment/get/" + id, JsonResult.class);
        if (responseEntity.getStatusCode().is2xxSuccessful()) {
            return responseEntity.getBody();
        } else {
            return new JsonResult<>("444", "操作失败", null);
        }
    }

    /**
     * 测试自己实现的负载均衡规则
     *
     * @return {@link String }
     * @author 张颖辉（zyh）
     * @date 2022/08/21
     * @version 1.0.0
     */
    @RequestMapping("payment/lb")
    public String getPaymentLB() {
        log.info(eurekaInstanceId + " getPaymentLB() 利用RestTemplate调用远程http服务/payment/lb");

        List<ServiceInstance> instances = discoveryClient.getInstances("CLOUD-PAYMENT-SERVICE");
        ServiceInstance serviceInstance = myLoadBalance.chooseServiceInstance(instances);
        URI uri = serviceInstance.getUri();

        return restTemplate.getForObject(uri + "/payment/lb", String.class);
    }
}
